
#include "GDFang.h"
#include "Toast.h"
#include <QMouseEvent>
#include <QMessageBox>
#include <QPushButton>
#include <QThread>
#include <QTimer>
#include <algorithm>

// 权重配置
const int WEIGHT_BASE = 2000;

GDFang::GDFang(QWidget *parent) : QWidget(parent)
{
    setWindowTitle("搁大方");
    setFixedSize(BOARD_SIZE * CELL_SIZE, (BOARD_SIZE + 2) * CELL_SIZE);
    resetGame();
    QPushButton *pPB = new QPushButton(this);
    pPB->setText("重新开始");
    pPB->setFixedSize(200, 40);
    pPB->move(BOARD_SIZE * CELL_SIZE / 2 - 100, (BOARD_SIZE + 1) * CELL_SIZE);
    connect(pPB, &QPushButton::clicked, [this]()
            { resetGame(); });
}

void GDFang::resetGame()
{
    aiLevel = MEDIUM;
    currentPlayer = PLAYER;
    gamePhase = PLACEMENT;
    selectedPiece = QPoint(-1, -1);
    removedPiece = QPoint(-1, -1);
    chances = 0;
    memset(board, EMPTY, sizeof(board));
    moveHistory.clear();
    vAvailableMoves.clear();
    update();
}

void GDFang::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    drawBoard(painter);
    drawPieces(painter);
    drawSelection(painter);
    highlightAvailableMoves(painter);
}

// 鼠标事件处理
void GDFang::mousePressEvent(QMouseEvent *event)
{
    QPoint pos(event->pos().x() / CELL_SIZE, event->pos().y() / CELL_SIZE);
    switch (gamePhase)
    {
    case PLACEMENT:
        handlePlacement(pos);
        break;
    case REMOVAL:
        handleRemoval(pos);
        break;
    case MOVEMENT:
        handleMovement(pos);
        break;
    }
}

// 落子处理
void GDFang::handlePlacement(QPoint pos)
{
    if (isValidMove(pos))
    {
        placePiece(pos, currentPlayer);

        if (checkWinCondition())
        {
            gameOver();
            return;
        }

        if (isBoardFull())
        {
            chances = 1;
            gamePhase = REMOVAL;
            QTimer::singleShot(1000, this, [this]()
                               { QMessageBox::information(this, "棋盘已满", "请移除对方一个棋子"); });
        }
        else
        {
            checkSpecialRules(pos);
            if (chances == 0)
            {
                switchPlayer();
            }
            else
            {
                update();
            }
        }
    }
}

// 处理移除阶段
void GDFang::handleRemoval(QPoint pos)
{
    // 只能移除对方棋子
    if (board[pos.x()][pos.y()] == getOpponent(currentPlayer))
    {
        bool bFull = isBoardFull();
        removePiece(pos);

        if (checkWinCondition())
        {
            gameOver();
            return;
        }
        if (chances == 0)
        {
            if (!bFull)
            {
                switchPlayer();
            }
            gamePhase = MOVEMENT;
        }
    }
}

// 处理移动阶段
void GDFang::handleMovement(QPoint pos)
{
    if (selectedPiece == QPoint(-1, -1))
    {
        // 选择要移动的己方棋子
        if (board[pos.x()][pos.y()] == currentPlayer)
        {
            selectedPiece = pos;
            vAvailableMoves.clear();
            QPoint pt = pos + QPoint(1, 0);
            if (isValidMove(pt))
            {
                vAvailableMoves.push_back(pt);
            }
            pt = pos + QPoint(-1, 0);
            if (isValidMove(pt))
            {
                vAvailableMoves.push_back(pt);
            }
            pt = pos + QPoint(0, -1);
            if (isValidMove(pt))
            {
                vAvailableMoves.push_back(pt);
            }
            pt = pos + QPoint(0, 1);
            if (isValidMove(pt))
            {
                vAvailableMoves.push_back(pt);
            }
            update();
        }
    }
    else
    {
        // 执行移动
        if (isValidMove(pos) && isAdjacent(selectedPiece, pos))
        {
            Piece temp = board[selectedPiece.x()][selectedPiece.y()];
            board[selectedPiece.x()][selectedPiece.y()] = EMPTY;
            placePiece(pos, temp);

            if (checkWinCondition())
            {
                gameOver();
                return;
            }

            // 检查特殊规则
            checkSpecialRules(pos);
            if (chances > 0)
            {
                gamePhase = REMOVAL;
            }
            else if (chances == 0)
            {
                gamePhase = MOVEMENT;
                switchPlayer();
            }
            selectedPiece = QPoint(-1, -1);
            vAvailableMoves.clear();
            update();
        }
    }
}

// 检查棋盘是否已满
bool GDFang::isBoardFull() const
{
    for (int x = 0; x < BOARD_SIZE; ++x)
        for (int y = 0; y < BOARD_SIZE; ++y)
            if (board[x][y] == EMPTY)
                return false;
    return true;
}

void GDFang::gameOver()
{
    QMessageBox::information(this, "游戏结束",
                             currentPlayer == PLAYER ? "玩家获胜!" : "电脑获胜!");
    resetGame();
}

void GDFang::switchPlayer()
{
    currentPlayer = (currentPlayer == PLAYER) ? AI_PIECE : PLAYER;
    if (currentPlayer == AI_PIECE)
    {
        QTimer::singleShot(1000, this, &GDFang::aiMove);
    }
}

// AI决策核心
void GDFang::aiMove()
{
    if (gamePhase == REMOVAL)
    {
        // 实现移除逻辑
        aiRemovePiece();
    }
    else if (gamePhase == MOVEMENT)
    {
        // 实现移动逻辑
        aiMovePiece();
    }
    else
    {
        // 落子阶段AI
        aiPlacePiece();
    }
    update();

    if (chances > 0 && currentPlayer == AI_PIECE)
    {
        QTimer::singleShot(1000, this, &GDFang::aiMove);
    }
}

// 胜负判定
bool GDFang::checkWinCondition() const
{
    if (gamePhase == PLACEMENT)
    {
        return false;
    }

    // 检查对方棋子是否存在
    Piece opponent = (currentPlayer == PLAYER) ? AI_PIECE : PLAYER;
    bool hasPieces = false;
    for (int x = 0; x < BOARD_SIZE; ++x)
    {
        for (int y = 0; y < BOARD_SIZE; ++y)
        {
            if (board[x][y] == opponent)
            {
                hasPieces = true;
                break;
            }
        }
        if (hasPieces)
            break;
    }
    return !hasPieces;
}

// 检查所有特殊规则
void GDFang::checkSpecialRules(QPoint pos)
{
    int squareCount = checkSquares(pos, currentPlayer);
    bool dragon = checkDragon(pos, currentPlayer);
    QString strT = (gamePhase == PLACEMENT ? "落子" : "吃子");

    // 检查两个方向的边界斜线
    for (int dir = 0; dir < 2; ++dir)
    {
        int diagonalCount = checkDiagonal(pos, dir, currentPlayer);

        // 只有连接到边界的斜线才计分
        if (diagonalCount >= 3)
        {
            chances += diagonalCount - 2;
            // Toast::showTip(QString("形成%1斜，获得%2次额外%3").arg(diagonalCount).arg(diagonalCount - 2).arg(strT), this);
            QMessageBox::information(this, QString("特殊规则"), QString("形成%1斜，获得%2次额外%3").arg(diagonalCount).arg(diagonalCount - 2).arg(strT));
        }
    }

    if (squareCount > 0)
    {
        chances += squareCount;
        // Toast::showTip(QString("形成%1方，获得%2次额外%3").arg(squareCount).arg(squareCount).arg(strT), this);
        QMessageBox::information(this, QString("特殊规则"), QString("形成%1方，获得%2次额外%3").arg(squareCount).arg(squareCount).arg(strT));
    }

    if (dragon)
    {
        chances += 4;
        // Toast::showTip(QString("形成一龙，获得4次额外%1").arg(strT), this);
        QMessageBox::information(this, QString("特殊规则"), QString("形成一龙，获得4次额外%1").arg(strT));
    }
}

// 斜线检查（严格边界验证）
int GDFang::checkDiagonal(QPoint pos, int dir, Piece targetPlayer) const
{
    int maxCount = 0;
    QVector<QPair<int, int>> directions;

    if (dir == 0)
    { // 左上到右下
        directions = {{1, 1}, {-1, -1}};
    }
    else
    { // 右上到左下
        directions = {{1, -1}, {-1, 1}};
    }

    for (auto &d : directions)
    {
        int count = 1;
        QPoint start = pos;
        QPoint end = pos;

        // 正向检测
        for (int i = 1;; ++i)
        {
            QPoint np = pos + QPoint(d.first * i, d.second * i);
            if (!isValidPos(np) || board[np.x()][np.y()] != targetPlayer)
                break;
            end = np;
            count++;
        }

        // 反向检测
        for (int i = 1;; ++i)
        {
            QPoint np = pos - QPoint(d.first * i, d.second * i);
            if (!isValidPos(np) || board[np.x()][np.y()] != targetPlayer)
                break;
            start = np;
            count++;
        }

        // 必须两端在边界
        if (isOnBorder(start) && isOnBorder(end))
        {
            maxCount = qMax(maxCount, count);
        }
    }
    return maxCount;
}

// 方阵检查
int GDFang::checkSquares(QPoint pos, Piece targetPlayer) const
{
    int count = 0;
    for (int dx = -1; dx <= 0; ++dx)
    {
        for (int dy = -1; dy <= 0; ++dy)
        {
            QPoint tl = pos + QPoint(dx, dy);
            if (tl.x() >= 0 && tl.y() >= 0 &&
                tl.x() + 1 < BOARD_SIZE && tl.y() + 1 < BOARD_SIZE)
            {
                if (board[tl.x()][tl.y()] == targetPlayer &&
                    board[tl.x() + 1][tl.y()] == targetPlayer &&
                    board[tl.x()][tl.y() + 1] == targetPlayer &&
                    board[tl.x() + 1][tl.y() + 1] == targetPlayer)
                {
                    count++;
                }
            }
        }
    }
    return count;
}

// 检查一龙规则
bool GDFang::checkDragon(QPoint pos, Piece targetPlayer) const
{
    // 检查水平方向
    int count = 1;
    int x = pos.x();
    int y = pos.y();
    for (int i = 1; i < 6; ++i)
    {
        if (x + i >= BOARD_SIZE || board[x + i][y] != targetPlayer)
            break;
        count++;
    }
    for (int i = 1; i < 6; ++i)
    {
        if (x - i < 0 || board[x - i][y] != targetPlayer)
            break;
        count++;
    }
    if (count >= 6)
        return true;

    // 检查垂直方向
    count = 1;
    for (int i = 1; i < 6; ++i)
    {
        if (y + i >= BOARD_SIZE || board[x][y + i] != targetPlayer)
            break;
        count++;
    }
    for (int i = 1; i < 6; ++i)
    {
        if (y - i < 0 || board[x][y - i] != targetPlayer)
            break;
        count++;
    }
    return count >= 6;
}

int GDFang::evaluatePosition(const QPoint &pos, Piece player, bool bFirst)
{
    int score = 0;

    // 检查一龙
    if (checkDragon(pos, player))
        score += 4 * WEIGHT_BASE;

    // 检查方阵
    int squares = checkSquares(pos, player);
    score += squares * WEIGHT_BASE;

    for (int dir = 0; dir < 2; ++dir)
    {
        int opponentDiag = checkDiagonal(pos, dir, player);
        if (opponentDiag >= 3)
        {                                        // 对手有形成长斜线的潜力
            score += opponentDiag * WEIGHT_BASE; // 阻断长斜线的战略价值
        }
    }

    // 边界位置基础分
    if (isOnBorder(pos))
    {
        // score += 300;
    }

    // 斜线/一龙潜力评估
    score += calculatePotential(pos, player);

    // 预测形成方阵的可能性（周围已有3子）
    int nearSquares = 0;
    for (int dx = -1; dx <= 1; ++dx)
    {
        for (int dy = -1; dy <= 1; ++dy)
        {
            QPoint np(pos.x() + dx, pos.y() + dy);
            if (isValidPos(np) && board[np.x()][np.y()] == player)
            {
                nearSquares++;
            }
        }
    }
    score += (nearSquares >= 3) ? WEIGHT_BASE * 0.1 : 0;

    if (bFirst)
    {
        Piece pc = board[pos.x()][pos.y()];
        Piece opponent = (player == PLAYER) ? AI_PIECE : PLAYER;
        board[pos.x()][pos.y()] = opponent;
        int opponentScore = evaluatePosition(pos, opponent, false);
        board[pos.x()][pos.y()] = pc;

        return score + opponentScore * 0.8; // 平衡攻防
    }
    else
    {
        return score;
    }
}

// 辅助功能
bool GDFang::isValidMove(QPoint pos) const
{
    return pos.x() >= 0 && pos.x() < BOARD_SIZE && pos.y() >= 0 && pos.y() < BOARD_SIZE && board[pos.x()][pos.y()] == EMPTY;
}

bool GDFang::isValidPos(QPoint pos) const
{
    return pos.x() >= 0 && pos.x() < BOARD_SIZE && pos.y() >= 0 && pos.y() < BOARD_SIZE;
}

bool GDFang::isOnBorder(QPoint pos) const
{
    return pos.x() == 0 || pos.x() == BOARD_SIZE - 1 || pos.y() == 0 || pos.y() == BOARD_SIZE - 1;
}

bool GDFang::isAdjacent(QPoint from, QPoint to) const
{
    return abs(from.x() - to.x()) + abs(from.y() - to.y()) == 1;
}

void GDFang::placePiece(QPoint pos, Piece piece)
{
    board[pos.x()][pos.y()] = piece;
    if (chances > 0)
    {
        chances--;
    }
    // if (gamePhase == MOVEMENT)
    {
        moveHistory.push(pos);
    }
    removedPiece = QPoint(-1, -1);
    update();
}

void GDFang::removePiece(QPoint pos)
{
    if (chances > 0)
    {
        chances--;
    }
    board[pos.x()][pos.y()] = EMPTY;
    removedPiece = pos;
    update();
}

GDFang::Piece GDFang::getOpponent(Piece player) const
{
    return (player == PLAYER) ? AI_PIECE : PLAYER;
}

// AI功能
QVector<GDFang::MoveResult> GDFang::generateMoves()
{
    QVector<MoveResult> moves;

    // 生成落子可能
    if (gamePhase == PLACEMENT)
    {
        for (int x = 0; x < BOARD_SIZE; ++x)
        {
            for (int y = 0; y < BOARD_SIZE; ++y)
            {
                if (board[x][y] == EMPTY)
                {
                    MoveResult mr;
                    mr.pos = QPoint(x, y);
                    mr.isMove = false;
                    mr.score = evaluatePosition(mr.pos, AI_PIECE);
                    moves.append(mr);
                }
            }
        }
    }
    else if (gamePhase == MOVEMENT)
    {
        // 生成移动可能
        for (int x = 0; x < BOARD_SIZE; ++x)
        {
            for (int y = 0; y < BOARD_SIZE; ++y)
            {
                if (board[x][y] != AI_PIECE)
                {
                    continue;
                }
                QPoint last = QPoint(x, y);
                for (int dx = -1; dx <= 1; ++dx)
                {
                    for (int dy = -1; dy <= 1; ++dy)
                    {
                        if (abs(dx) + abs(dy) != 1)
                            continue; // 只允许横向/纵向移动
                        int nx = last.x() + dx;
                        int ny = last.y() + dy;
                        if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == EMPTY)
                        {
                            MoveResult mr;
                            mr.from = last;
                            mr.pos = QPoint(nx, ny);
                            mr.isMove = true;
                            Piece from = board[last.x()][last.y()];
                            Piece pos = board[nx][ny];
                            if (from == AI_PIECE && pos == EMPTY)
                            {
                                // 模拟移动
                                board[last.x()][last.y()] = EMPTY;
                                board[nx][ny] = from;
                                mr.score = evaluatePosition(mr.pos, AI_PIECE);
                                board[nx][ny] = pos;
                                board[last.x()][last.y()] = from;
                                moves.append(mr);
                            }
                        }
                    }
                }
            }
        }
    }

    // 奖励叠加策略：寻找能同时形成斜线和方阵的位置
    for (auto &move : moves)
    {
        int multiBonus = 0;
        // 模拟落子
        board[move.pos.x()][move.pos.y()] = AI_PIECE;

        // 检查斜线奖励
        for (int dir = 0; dir < 2; ++dir)
        {
            int diag = checkDiagonal(move.pos, dir, currentPlayer);
            if (diag >= 3)
                multiBonus += (diag - 2) * 1000;
        }

        // 检查方阵奖励
        int squares = checkSquares(move.pos, currentPlayer);
        if (squares > 0)
            multiBonus += squares * 800;

        board[move.pos.x()][move.pos.y()] = EMPTY;
        move.score += multiBonus;
    }

    // 匹配3斜线潜在模式
    for (auto &move : moves)
    {
        // 检查是否形成三斜线种子
        int potential = calculatePotential(move.pos, AI_PIECE);
        move.score += 1200;
    }

    // 排序时优先考虑高复合奖励
    std::sort(moves.begin(), moves.end(), [](const MoveResult &a, const MoveResult &b)
              { return a.score > b.score; });

    return moves;
}

GDFang::MoveResult GDFang::findBestMove(int depth = 3)
{
    int actualDepth = depth;
    if (aiLevel == HARD)
    {
        // 根据剩余空格动态调整深度
        int emptyCount = 0;
        for (int x = 0; x < BOARD_SIZE; ++x)
            for (int y = 0; y < BOARD_SIZE; ++y)
                if (board[x][y] == EMPTY)
                    emptyCount++;
        actualDepth = emptyCount > 15 ? 5 : (emptyCount > 8 ? 4 : 3);
    }

    QVector<MoveResult> moves = generateMoves();
    if (moves.isEmpty())
        return MoveResult();

    // 前3层深度搜索
    for (auto &move : moves)
    {
        if (move.isMove)
        {
            // 执行移动
            Piece temp = board[move.from.x()][move.from.y()];
            board[move.from.x()][move.from.y()] = EMPTY;
            board[move.pos.x()][move.pos.y()] = temp;
        }
        else
        {
            board[move.pos.x()][move.pos.y()] = AI_PIECE;
        }

        move.score += minimax(depth - 1, false, INT_MIN, INT_MAX);

        // 撤销移动
        if (move.isMove)
        {
            board[move.pos.x()][move.pos.y()] = EMPTY;
            board[move.from.x()][move.from.y()] = AI_PIECE;
        }
        else
        {
            board[move.pos.x()][move.pos.y()] = EMPTY;
        }
    }

    return *std::max_element(moves.begin(), moves.end(),
                             [](const MoveResult &a, const MoveResult &b)
                             { return a.score < b.score; });
}

int GDFang::minimax(int depth, bool maximizingPlayer, int alpha, int beta)
{
    // 新增：动态调整搜索深度
    int remainingEmpty = 0;
    for (int x = 0; x < BOARD_SIZE; ++x)
        for (int y = 0; y < BOARD_SIZE; ++y)
            if (board[x][y] == EMPTY)
                remainingEmpty++;

    if (remainingEmpty < 10 && depth < 4)
    {
        depth += 2; // 终局阶段增加搜索深度
    }

    // 改进剪枝：当评估分差超过阈值时提前终止
    if (abs(alpha - beta) > 2500 && depth > 1)
    {
        return maximizingPlayer ? (beta - 1000) : (alpha + 1000);
    }
    // 增加快速评估剪枝
    if (depth > 2 && abs(alpha - beta) > 2000)
    {
        return maximizingPlayer ? beta : alpha; // 大幅差距时提前剪枝
    }

    // 动态调整末端搜索深度
    if (depth == 0 || checkWinCondition())
    {
        // 末端节点增加局部搜索
        int localScore = 0;
        for (int x = 0; x < BOARD_SIZE; ++x)
        {
            for (int y = 0; y < BOARD_SIZE; ++y)
            {
                if (board[x][y] == AI_PIECE)
                {
                    localScore += evaluatePosition(QPoint(x, y), AI_PIECE, false);
                }
            }
        }
        return localScore;
    }

    if (depth == 0)
    {
        if (moveHistory.size())
        {
            return evaluatePosition(moveHistory.top(), maximizingPlayer ? AI_PIECE : PLAYER);
        }
        else
        {
            return 0;
        }
    }

    auto moves = generateMoves();
    if (moves.isEmpty())
        return 0;

    if (maximizingPlayer)
    {
        int maxEval = INT_MIN;
        for (auto &move : moves)
        {
            // 模拟走棋
            if (move.isMove)
            { /* 处理移动逻辑 */
            }
            else
            {
                board[move.pos.x()][move.pos.y()] = AI_PIECE;
            }

            int eval = minimax(depth - 1, false, alpha, beta);
            maxEval = std::max(maxEval, eval);
            alpha = std::max(alpha, eval);

            // 撤销移动
            if (move.isMove)
            {
                board[move.pos.x()][move.pos.y()] = EMPTY;
                board[move.from.x()][move.from.y()] = AI_PIECE;
            }
            else
            {
                board[move.pos.x()][move.pos.y()] = EMPTY;
            }
            if (beta <= alpha)
                break;
        }
        return maxEval;
    }
    else
    {
        int minEval = INT_MAX;
        for (auto &move : moves)
        {
            // 模拟对手走棋
            if (move.isMove)
            { /* 处理移动逻辑 */
            }
            else
            {
                board[move.pos.x()][move.pos.y()] = PLAYER;
            }

            int eval = minimax(depth - 1, true, alpha, beta);
            minEval = std::min(minEval, eval);
            beta = std::min(beta, eval);

            // 撤销移动
            if (move.isMove)
            {
                board[move.pos.x()][move.pos.y()] = EMPTY;
                board[move.from.x()][move.from.y()] = AI_PIECE;
            }
            else
            {
                board[move.pos.x()][move.pos.y()] = EMPTY;
            }

            if (beta <= alpha)
                break;
        }
        return minEval;
    }
}

// 评估方法
int GDFang::evaluateThreat(QPoint pos)
{
    int score = 0;
    int t;
    if (isBoardFull())
    {
        // 棋盘满时拿掉对方的棋子时，附近有己方的棋子才有意义
        for (int dx = -1; dx <= 1; ++dx)
        {
            for (int dy = -1; dy <= 1; ++dy)
            {
                if (abs(dx) + abs(dy) != 1)
                    continue; // 只允许横向/纵向移动
                int nx = pos.x() + dx;
                int ny = pos.y() + dy;
                if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == currentPlayer)
                {
                    t = evaluateMove(QPoint(nx, ny), pos);
                    if(t > score)
                    {
                        score = t;
                    }
                }
            }
        }
        board[pos.x()][pos.y()] = getOpponent(currentPlayer);
        return score;
    }

    // 计算该棋子的战略价值
    for (int dir = 0; dir < 2; ++dir)
    {
        t = checkDiagonal(pos, dir, currentPlayer);
        if (t >= 3)
        {
            score += (t - 2) * WEIGHT_BASE;
        }
    }
    score += checkSquares(pos, currentPlayer) * WEIGHT_BASE;
    if (checkDragon(pos, currentPlayer))
        score += WEIGHT_BASE * 4;

    // 考虑棋子位置价值
    if (pos.x() >= 2 && pos.x() <= 3 && pos.y() >= 2 && pos.y() <= 3)
        score += WEIGHT_BASE;

    return score;
}

int GDFang::evaluateMove(QPoint from, QPoint to)
{
    int score = 0;
    int t = 0;
    board[from.x()][from.y()] = EMPTY;
    board[to.x()][to.y()] = currentPlayer;
    // 是否形成新棋型
    for (int dir = 0; dir < 2; ++dir)
    {
        t = checkDiagonal(to, dir, currentPlayer);
        if (t >= 3)
        {
            score += (t - 2) * WEIGHT_BASE;
        }
    }
    score += checkSquares(to, currentPlayer) * WEIGHT_BASE;
    if (checkDragon(to, currentPlayer))
    {
        score += 4 * WEIGHT_BASE;
    }

    // 评估是否阻断对手的潜在连线
    Piece opponent = getOpponent(currentPlayer);
    int maxThreat = 0;
    for (int dx = -1; dx <= 1; ++dx)
    {
        for (int dy = -1; dy <= 1; ++dy)
        {
            QPoint np(to.x() + dx, to.y() + dy);
            if (isValidPos(np) && board[np.x()][np.y()] == opponent)
            {
                board[np.x()][np.y()] = EMPTY;
                board[to.x()][to.y()] = opponent;
                int opponentThreat = 0;
                for (int dir = 0; dir < 2; ++dir)
                {
                    t = checkDiagonal(to, dir, opponent);
                    if (t >= 3)
                    {
                        opponentThreat += (t - 2) * WEIGHT_BASE;
                    }
                }
                opponentThreat += checkSquares(to, opponent) * WEIGHT_BASE;
                if (checkDragon(to, opponent))
                {
                    opponentThreat += 4 * WEIGHT_BASE;
                }
                board[np.x()][np.y()] = opponent;
                board[to.x()][to.y()] = EMPTY;
                if (opponentThreat > maxThreat)
                {
                    maxThreat = opponentThreat;
                }
            }
        }
    }
    score += maxThreat * 0.2;
    
    // 给对手让出位置，对手是否形成威胁
    maxThreat = 0;
    for (int dx = -1; dx <= 1; ++dx)
    {
        for (int dy = -1; dy <= 1; ++dy)
        {
            QPoint np(from.x() + dx, from.y() + dy);
            if (isValidPos(np) && board[np.x()][np.y()] == opponent)
            {
                board[np.x()][np.y()] = EMPTY;
                board[from.x()][from.y()] = opponent;
                int opponentThreat = 0;
                for (int dir = 0; dir < 2; ++dir)
                {
                    t = checkDiagonal(from, dir, opponent);
                    if (t >= 3)
                    {
                        opponentThreat += (t - 2) * WEIGHT_BASE;
                    }
                }
                opponentThreat += checkSquares(from, opponent) * WEIGHT_BASE;
                if (checkDragon(from, opponent))
                {
                    opponentThreat += 4 * WEIGHT_BASE;
                }
                board[np.x()][np.y()] = opponent;
                board[from.x()][from.y()] = EMPTY;
                if (opponentThreat > maxThreat)
                {
                    maxThreat = opponentThreat;
                }
            }
        }
    }
    score -= maxThreat * 0.2;

    // 新增：移动后形成的战略控制区域
    int controlScore = 0;
    for (int dx = -2; dx <= 2; ++dx)
    {
        for (int dy = -2; dy <= 2; ++dy)
        {
            QPoint np(to.x() + dx, to.y() + dy);
            if (isValidMove(np))
            {
                // 控制范围3x3区域的中心价值
                controlScore += (3 - (abs(dx) + abs(dy))) * WEIGHT_BASE;
            }
        }
    }
    score += controlScore * 0.05;

    // 恢复棋盘状态
    board[from.x()][from.y()] = currentPlayer;
    board[to.x()][to.y()] = EMPTY;
    return score;
}

int GDFang::calculatePotential(QPoint pos, Piece piece)
{
    int score = 0;
    Piece current = board[pos.x()][pos.y()];
    QVector<QPair<int, int>> directions;
    for (int dir = 0; dir < 4; dir++)
    {
        switch (dir)
        {
        case 0:
            directions = {{1, 1}, {-1, -1}};
            break;
        case 1:
            directions = {{1, -1}, {-1, 1}};
            break;
        case 2:
            directions = {{1, 0}, {-1, 0}};
            break;
        case 3:
            directions = {{0, -1}, {0, 1}};
            break;
        }

        // 向两个方向探测
        int totle = 0;
        int self = 0;
        int potential = 0;
        for (int i = 1; i <= 5; ++i)
        {
            QPoint nps[2] = {
                pos + QPoint(i * directions[dir & 0x01].first, i * directions[dir & 0x01].second),
                pos - QPoint(i * directions[dir & 0x01].first, i * directions[dir & 0x01].second)};

            for (int j = 0; j < 2; j++)
            {
                if (isValidPos(nps[j]))
                {
                    totle++;
                    if ((board[nps[j].x()][nps[j].y()] == EMPTY || board[nps[j].x()][nps[j].y()] == piece))
                    {
                        if (board[nps[j].x()][nps[j].y()] == piece)
                        {
                            self++;
                        }

                        if (isOnBorder(nps[j]))
                            potential++;
                    }
                }
            }
        }
        if (potential == 2)
        {
            totle++;
            score += WEIGHT_BASE * 0.1 * self / totle;
        }
    }
    return score;
}

void GDFang::aiRemovePiece()
{
    // 寻找最有价值的对方棋子移除
    QVector<QPoint> targets;
    int maxScore = -1;

    Piece opponent = getOpponent(currentPlayer);
    for (int x = 0; x < BOARD_SIZE; ++x)
    {
        for (int y = 0; y < BOARD_SIZE; ++y)
        {
            if (board[x][y] == opponent)
            {
                QPoint pos(x, y);
                int score = evaluateThreat(pos);
                if (score > maxScore)
                {
                    maxScore = score;
                    targets.clear();
                    targets.append(pos);
                }
                else if (score == maxScore)
                {
                    targets.append(pos);
                }
            }
        }
    }

    if (!targets.isEmpty())
    {
        bool bFull = isBoardFull();
        QPoint target = targets[qrand() % targets.size()];
        removePiece(target);

        if (checkWinCondition())
        {
            gameOver();
            return;
        }

        if (chances == 0)
        {
            gamePhase = MOVEMENT;
            if (bFull)
            {
                QTimer::singleShot(1000, this, &GDFang::aiMove);
            }
            else
            {
                switchPlayer();
            }
        }
    }
    else
    {
        gameOver();
    }
}

void GDFang::aiMovePiece()
{
    // 寻找最佳移动位置
    QVector<MoveResult> moves;

    // 生成所有可能的移动
    for (int x = 0; x < BOARD_SIZE; ++x)
    {
        for (int y = 0; y < BOARD_SIZE; ++y)
        {
            if (board[x][y] == currentPlayer)
            {
                for (int dx = -1; dx <= 1; ++dx)
                {
                    for (int dy = -1; dy <= 1; ++dy)
                    {
                        if (abs(dx) + abs(dy) != 1)
                            continue;
                        int nx = x + dx;
                        int ny = y + dy;
                        if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == EMPTY)
                        {
                            MoveResult mc;
                            mc.from = QPoint(x, y);
                            mc.pos = QPoint(nx, ny);
                            mc.score = evaluateMove(mc.from, mc.pos);
                            moves.append(mc);
                        }
                    }
                }
            }
        }
    }

    if (!moves.isEmpty())
    {
        // 选择最高分移动
        std::sort(moves.begin(), moves.end(),
                  [](const MoveResult &a, const MoveResult &b)
                  {
                      return a.score > b.score;
                  });

        MoveResult best = moves.first();
        Piece temp = board[best.from.x()][best.from.y()];
        board[best.from.x()][best.from.y()] = EMPTY;
        placePiece(best.pos, temp);

        if (checkWinCondition())
        {
            gameOver();
            return;
        }
        // 检查特殊规则
        checkSpecialRules(best.pos);
        if (chances > 0)
        {
            gamePhase = REMOVAL;
        }
        else if (chances == 0)
        {
            gamePhase = MOVEMENT;
            switchPlayer();
        }
    }
}

// 在AI决策中根据难度调整搜索深度
void GDFang::aiPlacePiece()
{
    // 前1步优先占据关键位置点，太多了死板反而变傻
    if (moveHistory.size() < 3)
    {
        QVector<QPoint> earlyPoints = {
            QPoint(1, 1), QPoint(4, 4), QPoint(1, 4), QPoint(4, 1), // 四个次角落，三斜中间点
        };

        for (auto &pos : earlyPoints)
        {
            if (board[pos.x()][pos.y()] == EMPTY)
            {
                placePiece(pos, AI_PIECE);
                switchPlayer();
                return;
            }
        }
    }

    /*
    // 优先检测可形成三斜的中间点
    QVector<QPoint> triplePoints;
    for (int x = 1; x < 5; ++x)
    {
        for (int y = 1; y < 5; ++y)
        {
            QPoint pos(x, y);
            // 检查是否在两个方向均具备形成三斜的潜力
            int dir0_pot = calculatePotential(pos, 0, AI_PIECE);
            int dir1_pot = calculatePotential(pos, 1, AI_PIECE);
            if (dir0_pot >= 2 || dir1_pot >= 2)
            {
                triplePoints.append(pos);
            }
        }
    }

    // 动态选择价值最高的中间点
    if (!triplePoints.isEmpty())
    {
        MoveResult bestTriple;
        bestTriple.score = -1;
        for (auto &pos : triplePoints)
        {
            int score = evaluatePosition(pos, AI_PIECE);
            if (score > bestTriple.score)
            {
                bestTriple.pos = pos;
                bestTriple.score = score;
            }
        }
        placePiece(bestTriple.pos, AI_PIECE);
        checkSpecialRules(bestTriple.pos);
        if (chances == 0)
        {
            switchPlayer();
        }
        return;
    }
    //*/

    // 检查预定义模式（例如四方包围圈）
    QVector<QPoint> keyPositions;
    keyPositions << QPoint(2, 2) << QPoint(3, 3) << QPoint(2, 3) << QPoint(3, 2);
    for (auto &pos : keyPositions)
    {
        if (board[pos.x()][pos.y()] == EMPTY)
        {
            int score = evaluatePosition(pos, AI_PIECE);
            if (score > 5000)
            { // 高价值中心位置
                placePiece(pos, AI_PIECE);
                checkSpecialRules(pos);
                if (chances == 0)
                {
                    switchPlayer();
                }
                return;
            }
        }
    }

    int depth = 3;
    switch (aiLevel)
    {
    case EASY:
        depth = 1;
        break;
    case HARD:
        depth = 5;
        break;
    }
    // 使用minimax算法进行决策
    MoveResult best = findBestMove(depth);

    if (best.pos != QPoint(-1, -1))
    {
        if (best.isMove)
        {
            // 执行棋子移动
            board[best.from.x()][best.from.y()] = EMPTY;
            placePiece(best.pos, AI_PIECE);
        }
        else
        {
            placePiece(best.pos, AI_PIECE);
        }

        if (checkWinCondition())
        {
            gameOver();
            return;
        }
        if (isBoardFull())
        {
            chances = 1;
            gamePhase = REMOVAL;
            //QTimer::singleShot(1000, this, &GDFang::aiMove);
        }
        else
        {
            checkSpecialRules(best.pos);
            if (chances == 0)
            {
                switchPlayer();
            }
        }
    }
}

// 绘图功能
// 绘制棋盘
void GDFang::drawBoard(QPainter &painter)
{
    painter.drawPixmap(0,0,QPixmap(":/res/background.jpg"));
    painter.setPen(QPen(Qt::black, 2));
    int nOffset = CELL_SIZE >> 1;
    for (int i = 0; i < BOARD_SIZE; ++i)
    {
        painter.drawLine(nOffset, i * CELL_SIZE + nOffset,
                         (BOARD_SIZE - 0.5) * CELL_SIZE, i * CELL_SIZE + nOffset);
        painter.drawLine(i * CELL_SIZE + nOffset, nOffset,
                         i * CELL_SIZE + nOffset, (BOARD_SIZE - 0.5) * CELL_SIZE);
    }
}

// 绘制棋子
void GDFang::drawPieces(QPainter &painter)
{
    QFont font("楷体", 24);
    painter.setFont(font);

    for (int x = 0; x < BOARD_SIZE; ++x)
    {
        for (int y = 0; y < BOARD_SIZE; ++y)
        {
            if (board[x][y] != EMPTY)
            {
                QRect rect(x * CELL_SIZE + 9, y * CELL_SIZE + 9, CELL_SIZE - 18, CELL_SIZE - 18);
                painter.setPen(Qt::darkMagenta);
                painter.setBrush(board[x][y] == PLAYER ? QColor(139, 69, 19) : Qt::white);
                painter.drawEllipse(rect);

                painter.setPen(board[x][y] == PLAYER ? Qt::white : Qt::black);
                painter.drawText(rect, Qt::AlignCenter, board[x][y] == PLAYER ? "方" : "正");
            }
        }
    }

    painter.setPen(currentPlayer == PLAYER ? Qt::red : Qt::black);
    char szT[128];
    if (gamePhase == MOVEMENT)
    {
        sprintf(szT, "%s请选中己方一子进行移动，只能上下左右移动一格到空白位置，不能斜着移动",
                currentPlayer == PLAYER ? "玩家" : "电脑");
    }
    else
    {
        if (chances == 0)
        {
            sprintf(szT, "轮到%s%s",
                    currentPlayer == PLAYER ? "玩家" : "电脑",
                    gamePhase == PLACEMENT ? "落子" : "吃子");
        }
        else
        {
            sprintf(szT, "%s还有%d次%s",
                    currentPlayer == PLAYER ? "玩家" : "电脑",
                    chances,
                    gamePhase == PLACEMENT ? "落子" : "吃子");
        }
    }
    painter.drawText(25, BOARD_SIZE * CELL_SIZE + (CELL_SIZE >> 1), szT);
}

void GDFang::drawSelection(QPainter &painter)
{
    if (selectedPiece != QPoint(-1, -1))
    {
        painter.setBrush(Qt::NoBrush);
        painter.setPen(Qt::blue);
        painter.drawRect(selectedPiece.x() * CELL_SIZE + 7, selectedPiece.y() * CELL_SIZE + 7, CELL_SIZE - 14, CELL_SIZE - 14);
    }
    if (removedPiece != QPoint(-1, -1))
    {
        painter.setBrush(Qt::NoBrush);
        painter.setPen(Qt::lightGray);
        painter.drawEllipse(removedPiece.x() * CELL_SIZE + 7, removedPiece.y() * CELL_SIZE + 7, CELL_SIZE - 14, CELL_SIZE - 14);
    }
}

// 高亮可用移动位置
void GDFang::highlightAvailableMoves(QPainter &painter)
{
    // 在棋子周围显示可移动位置
    painter.setBrush(Qt::NoBrush);
    painter.setPen(Qt::green);
    for (QPoint pt : vAvailableMoves)
    {
        painter.drawRect(pt.x() * CELL_SIZE + 7, pt.y() * CELL_SIZE + 7, CELL_SIZE - 14, CELL_SIZE - 14);
    }
}
